home *** CD-ROM | disk | FTP | other *** search
- /*
- File: DZInput.c
-
- Contains: xxx put contents here xxx
-
- Version: xxx put version here xxx
-
- Copyright: © 1998 by Apple Computer, Inc., all rights reserved.
-
- File Ownership:
-
- DRI: xxx put dri here xxx
-
- Other Contact: xxx put other contact here xxx
-
- Technology: xxx put technology here xxx
-
- Writers:
-
- (BWS) Brent Schorsch
- (sjb) Steve Bollinger
-
- Change History (most recent first):
-
- <SP15> 10/20/98 BWS Pause and Quit are now separate needs
- <14> 6/18/98 sjb InputSprocket.h comes from <> place
- */
-
- /*
- * File: DZInput.c
- *
- * Contents: Handles input devices.
- *
- * Copyright © 1996 Apple Computer, Inc.
- */
-
- #include <TextUtils.h>
-
- #define USE_OLD_INPUT_SPROCKET_LABELS 0
- #define USE_OLD_ISPNEED_STRUCT 0
- #include <InputSprocket.h>
-
- #include "DZGame.h"
- #include "DZInput.h"
- #include "DZResource.h"
-
- #define USE_MOUSE_AND_KEYBOARD 1
-
- #define ISpSymmetricAxisToFloat(axis) ((((float) axis) - kISpAxisMiddle) / (kISpAxisMaximum-kISpAxisMiddle))
- #define ISpAsymmetricAxisToFloat(axis) (((float) axis) / (kISpAxisMaximum))
-
- /*
- enum {
- kElement_Fire,
- kElement_Pause,
- kElement_ShowHUD,
- kElement_ShowFPS,
- kElement_Turn,
- kElement_COUNT
- };
- */
-
- enum
- {
- kNeed_Fire,
- kNeed_Roll,
- kNeed_Pitch,
- kNeed_Throttle,
- kNeed_ThrottleUp,
- kNeed_ThrottleDown,
- kNeed_ThrottleFull,
- kNeed_ThrottleZero,
- kNeed_InertialDampers,
- kNeed_Yaw,
- kNeed_YawLeft,
- kNeed_YawCenter,
- kNeed_YawRight,
- kNeed_ShowHUD,
- kNeed_ShowFPS,
- kNeed_ShowThrottle,
- kNeed_ShowVelocity,
- kNeed_InstantStop,
- kNeed_Pause,
- kNeed_COUNT
- };
-
- #define kNeedsVersion 1
-
- static Boolean gInputActive = false;
- static ISpElementListReference gInputEventList = NULL;
- static ISpElementListReference gInputHoldDownEventList = NULL;
- static ISpElementListReference gInputYawEventList = NULL;
- static ISpElementListReference gInputThrottleEventList = NULL;
- static ISpElementReference gInputElement[kNeed_COUNT] = {NULL, NULL, NULL, NULL, NULL};
-
-
- /* =============================================================================
- * Input_Init (external)
- *
- * Initializes the Input stuff.
- * ========================================================================== */
- void Input_Init(
- void)
- {
- UInt32 itr;
-
- ISpNeed needs[kNeed_COUNT] =
- {
- { "\pFire", kIconSuiteID_Fire, 0, 0,
- kISpElementKind_Button,
- kISpElementLabel_Btn_Fire,
- 0, 0, 0, 0
- },
- { "\pRoll", kIconSuiteID_Roll, 0, 0,
- kISpElementKind_Axis,
- kISpElementLabel_Axis_Roll,
- 0, 0, 0, 0
- },
- { "\pPitch", kIconSuiteID_Pitch, 0, 0,
- kISpElementKind_Axis,
- kISpElementLabel_Axis_Pitch,
- 0, 0, 0, 0
- },
- { "\pThrottle", kIconSuiteID_Throttle, 0, 1,
- kISpElementKind_Axis,
- kISpElementLabel_Axis_Throttle,
- kISpNeedFlag_Axis_AlreadyButton | kISpNeedFlag_Axis_Asymetric, 0, 0, 0
- },
- { "\pIncrease Throttle", kIconSuiteID_ThrottleUp, 0, 1,
- kISpElementKind_Button,
- kISpElementLabel_None,
- kISpNeedFlag_Button_AlreadyAxis, 0, 0, 0
- },
- { "\pDecrease Throttle", kIconSuiteID_ThrottleDown, 0, 1,
- kISpElementKind_Button,
- kISpElementLabel_None,
- kISpNeedFlag_Button_AlreadyAxis, 0, 0, 0
- },
- { "\pThrottle Max", kIconSuiteID_ThrottleMax, 0, 1,
- kISpElementKind_Button,
- kISpElementLabel_None,
- kISpNeedFlag_Button_AlreadyAxis, 0, 0, 0
- },
- { "\pThrottle Min", kIconSuiteID_ThrottleMin, 0, 1,
- kISpElementKind_Button,
- kISpElementLabel_None,
- kISpNeedFlag_Button_AlreadyAxis, 0, 0, 0
- },
- { "\pInertial Dampers", kIconSuiteID_InertialDampers, 0, 0,
- kISpElementKind_Button,
- kISpElementLabel_None,
- 0, 0, 0, 0
- },
- { "\pRudder", kIconSuiteID_Rudder, 0, 2,
- kISpElementKind_Axis,
- kISpElementLabel_Axis_Rudder,
- kISpNeedFlag_Axis_AlreadyButton, 0, 0, 0
- },
- { "\pYaw Left", kIconSuiteID_RudderLeft, 0, 2,
- kISpElementKind_Button,
- kISpElementLabel_Btn_LookLeft,
- kISpNeedFlag_Button_AlreadyAxis, 0, 0, 0
- },
- { "\pYaw Center", kIconSuiteID_RudderCenter, 0, 2,
- kISpElementKind_Button,
- kISpElementLabel_None,
- kISpNeedFlag_Button_AlreadyAxis, 0, 0, 0
- },
- { "\pYaw Right", kIconSuiteID_RudderRight, 0, 2,
- kISpElementKind_Button,
- kISpElementLabel_Btn_LookRight,
- kISpNeedFlag_Button_AlreadyAxis, 0, 0, 0
- },
- { "\pShow HUD", kIconSuiteID_ShowHUD, 0, 0,
- kISpElementKind_Button,
- kISpElementLabel_None,
- 0, 0, 0, 0
- },
- { "\pShow FPS", kIconSuiteID_ShowFPS, 0, 0,
- kISpElementKind_Button,
- kISpElementLabel_None,
- 0, 0, 0, 0
- },
- { "\pShow Throttle", kIconSuiteID_ShowThrottle, 0, 0,
- kISpElementKind_Button,
- kISpElementLabel_None,
- 0, 0, 0, 0
- },
- { "\pShow Velocity", kIconSuiteID_ShowVelocity, 0, 0,
- kISpElementKind_Button,
- kISpElementLabel_None,
- 0, 0, 0, 0
- },
- { "\pInstant Stop", kIconSuiteID_InstantStop, 0, 0,
- kISpElementKind_Button,
- kISpElementLabel_None,
- 0, 0, 0, 0
- },
- { "\pPause", kIconSuiteID_Pause, 0, 0,
- kISpElementKind_Button,
- kISpElementLabel_Btn_StartPause,
- 0, 0, 0, 0
- }
- };
-
- // Get the names for the needs
- for (itr = 0; itr < kNeed_COUNT; itr++)
- GetIndString(needs[itr].name, kStrListID_NeedsNames, itr+1);
-
- #if USE_MOUSE_AND_KEYBOARD
-
- // Enable the mouse
- ISpDevices_ActivateClass (kISpDeviceClass_Mouse);
-
- // Enable the keyboard
- ISpDevices_ActivateClass (kISpDeviceClass_Keyboard);
- #endif
-
- // Set our virtual elements
- ISpElement_NewVirtualFromNeeds(kNeed_COUNT, needs, gInputElement, 0);
-
- // Autoconfigure our virtual elements based on our needs
- ISpInit(kNeed_COUNT, needs, gInputElement, ' dz ', kNeedsVersion, 0, kSetListID, 0);
-
- // Build two lists of elements, which we'll poll for events
- // the 'hold down' list reports both up and down events
- ISpElementList_New(0, NULL, &gInputEventList, 0);
- ISpElementList_New(0, NULL, &gInputHoldDownEventList, 0);
-
- // Add the virtual elements one at a time so we can assign a refcon
- ISpElementList_AddElements(gInputHoldDownEventList, kInputEvent_Fire_On,1, &gInputElement[kNeed_Fire]);
-
- ISpElementList_AddElements(gInputHoldDownEventList, kInputEvent_InertialDampers_On,
- 1, &gInputElement[kNeed_InertialDampers]);
-
- ISpElementList_AddElements(gInputEventList, kInputEvent_InstantStop, 1, &gInputElement[kNeed_InstantStop]);
-
- ISpElementList_AddElements(gInputEventList, kInputEvent_ShowHUD, 1, &gInputElement[kNeed_ShowHUD]);
- ISpElementList_AddElements(gInputEventList, kInputEvent_ShowFPS, 1, &gInputElement[kNeed_ShowFPS]);
- ISpElementList_AddElements(gInputEventList, kInputEvent_ShowThrottle, 1, &gInputElement[kNeed_ShowThrottle]);
- ISpElementList_AddElements(gInputEventList, kInputEvent_ShowVelocity, 1, &gInputElement[kNeed_ShowVelocity]);
-
- ISpElementList_AddElements(gInputEventList, kInputEvent_Pause, 1, &gInputElement[kNeed_Pause]);
-
-
- // Build our list of elements used for the rudder (yaw) when from buttons
- ISpElementList_New(0, NULL, &gInputYawEventList, 0);
-
- // Add the virtual elements one at a time so we can assign a refcon
- ISpElementList_AddElements(gInputYawEventList, kNeed_YawLeft, 1, &gInputElement[kNeed_YawLeft]);
- ISpElementList_AddElements(gInputYawEventList, kNeed_YawCenter, 1, &gInputElement[kNeed_YawCenter]);
- ISpElementList_AddElements(gInputYawEventList, kNeed_YawRight, 1, &gInputElement[kNeed_YawRight]);
-
-
- // Build our list of elements used for the throttle when from buttons
- ISpElementList_New(0, NULL, &gInputThrottleEventList, 0);
-
- // Add the virtual elements one at a time so we can assign a refcon
- ISpElementList_AddElements(gInputThrottleEventList, kNeed_ThrottleUp, 1, &gInputElement[kNeed_ThrottleUp]);
- ISpElementList_AddElements(gInputThrottleEventList, kNeed_ThrottleDown, 1, &gInputElement[kNeed_ThrottleDown]);
- ISpElementList_AddElements(gInputThrottleEventList, kNeed_ThrottleFull, 1, &gInputElement[kNeed_ThrottleFull]);
- ISpElementList_AddElements(gInputThrottleEventList, kNeed_ThrottleZero, 1, &gInputElement[kNeed_ThrottleZero]);
-
- // Start off suspended (because the game is stopped)
- ISpSuspend();
- }
-
-
- /* =============================================================================
- * Input_Exit (external)
- *
- * Prepares for exit.
- * ========================================================================== */
- void Input_Exit(
- void)
- {
- if (gInputActive)
- {
- Input_Activate(false);
- }
-
- if (gInputEventList != NULL)
- {
- ISpElementList_Dispose(gInputEventList);
- gInputEventList = NULL;
- }
-
- if (gInputHoldDownEventList != NULL)
- {
- ISpElementList_Dispose(gInputHoldDownEventList);
- gInputHoldDownEventList = NULL;
- }
-
- ISpStop();
-
- ISpElement_DisposeVirtual(kNeed_COUNT, gInputElement);
- }
-
-
- /* =============================================================================
- * Input_Configure (external)
- *
- * Show the configuration dialog.
- * ========================================================================== */
- void Input_Configure(
- void)
- {
- ISpConfigure(NULL);
- }
-
- #if 0
- /* =============================================================================
- * Input_GetState (external)
- *
- * This routine handles the elements that are polled. It returns in outXTurn
- * and outYTurn the "turn" controls in the ±1 range.
- * ========================================================================== */
- void Input_GetState(
- float* outXTurn,
- float* outYTurn)
- {
- ISpMovementData movementData;
- double xTurn = 0.0;
- double yTurn = 0.0;
-
- if (gInputActive)
- {
- // Get the data
- ISpElement_GetComplexState(
- gInputElement[kNeed_Turn],
- sizeof(ISpMovementData),
- &movementData);
-
- // Turn 'em into ±1 float range
- xTurn = movementData.xAxis;
- xTurn -= kISpAxisMiddle;
- xTurn /= kISpAxisMaximum-kISpAxisMiddle;
-
- yTurn = movementData.yAxis;
- yTurn -= kISpAxisMiddle;
- yTurn /= kISpAxisMaximum-kISpAxisMiddle;
- yTurn *= -1; // reverse axis
- }
-
- // Return the values
- *outXTurn = xTurn;
- *outYTurn = yTurn;
- }
- #endif
-
- float Input_GetRoll (void)
- {
- ISpAxisData axisValue = kISpAxisMiddle;
-
- (void) ISpElement_GetSimpleState(gInputElement[kNeed_Roll], &axisValue);
- return ISpSymmetricAxisToFloat (axisValue);
- }
-
- float Input_GetPitch (void)
- {
- ISpAxisData axisValue = kISpAxisMiddle;
-
- (void) ISpElement_GetSimpleState(gInputElement[kNeed_Pitch], &axisValue);
- return (-1.0 * ISpSymmetricAxisToFloat (axisValue));
- }
-
- float Input_GetYaw (void)
- {
- static float gYawValue = 0.0;
- static Boolean gYawInitalized = false;
-
- float yawValue = gYawValue;
- OSStatus error = noErr;
- ISpAxisData axisValue;
- Boolean wasEvent;
- ISpElementEvent event;
-
- // should probably put the initialization check somewhere else, so does not do it every time
- if (!gYawInitalized)
- {
- (void) ISpElement_GetSimpleState(gInputElement[kNeed_Yaw], &axisValue);
- gYawValue = ISpSymmetricAxisToFloat (axisValue);
-
- gYawInitalized = true;
- }
-
- // we check the axis, to see if IT was moved, if so, we use that value
- wasEvent = false;
- error = ISpElement_GetNextEvent (gInputElement[kNeed_Yaw], sizeof (event), &event, &wasEvent);
- if (!error && wasEvent)
- {
- error = ISpElement_GetSimpleState(gInputElement[kNeed_Yaw], &axisValue);
- if (!error) yawValue = ISpSymmetricAxisToFloat (axisValue);
-
- ISpElement_Flush(gInputElement[kNeed_Yaw]);
- }
- else do
- {
- error = ISpElementList_GetNextEvent (gInputYawEventList, sizeof (event), &event, &wasEvent);
-
- // only process valid keydown events (all the yaw events ignore button ups)
- if (wasEvent && !error && (event.data == kISpButtonDown))
- {
- UInt32 keyFunction = event.refCon; // because we set it this way
- switch (keyFunction)
- {
- case kNeed_YawLeft:
- yawValue -= 0.1;
- if (yawValue < -1.0) yawValue = -1.0;
- break;
- case kNeed_YawCenter:
- yawValue = 0.0;
- break;
- case kNeed_YawRight:
- yawValue += 0.1;
- if (yawValue > 1.0) yawValue = 1.0;
- break;
- }
- }
- }
- while (wasEvent && !error);
-
- gYawValue = yawValue;
-
- return yawValue;
- }
-
- float Input_GetThrottle (void)
- {
- static float gThrottleValue = 0.0;
- static Boolean gThrottleInitialized = false;
-
- float throttleValue = gThrottleValue;
- OSStatus error = noErr;
- ISpAxisData axisValue;
- Boolean wasEvent;
- ISpElementEvent event;
-
- // should probably put the initialization check somewhere else, so does not do it every time
- if (!gThrottleInitialized)
- {
- (void) ISpElement_GetSimpleState(gInputElement[kNeed_Throttle], &axisValue);
- gThrottleValue = ISpAsymmetricAxisToFloat (axisValue);
-
- gThrottleInitialized = true;
- }
-
- // we check the axis, to see if IT was moved, if so, we use that value
- wasEvent = false;
- error = ISpElement_GetNextEvent (gInputElement[kNeed_Throttle], sizeof (event), &event, &wasEvent);
- if (!error && wasEvent)
- {
- error = ISpElement_GetSimpleState(gInputElement[kNeed_Throttle], &axisValue);
- if (!error) throttleValue = ISpAsymmetricAxisToFloat (axisValue);
-
- ISpElement_Flush(gInputElement[kNeed_Throttle]);
- }
- else do
- {
- error = ISpElementList_GetNextEvent (gInputThrottleEventList, sizeof (event), &event, &wasEvent);
-
- // only process valid keydown events (all the throttle events ignore button ups)
- if (wasEvent && !error && (event.data == kISpButtonDown))
- {
- UInt32 keyFunction = event.refCon; // because we set it this way
- switch (keyFunction)
- {
- case kNeed_ThrottleUp:
- throttleValue += 0.05;
- if (throttleValue > 1.0) throttleValue = 1.0;
- break;
- case kNeed_ThrottleDown:
- throttleValue -= 0.05;
- if (throttleValue < 0.0) throttleValue = 0.0;
- break;
- case kNeed_ThrottleFull:
- throttleValue = 1.0;
- break;
- case kNeed_ThrottleZero:
- throttleValue = 0.0;
- break;
- }
- }
- }
- while (wasEvent && !error);
-
- gThrottleValue = throttleValue;
-
- return throttleValue;
- }
-
-
-
- /* =============================================================================
- * Input_GetEvent (external)
- *
- * This routine handles the elements that are event-based. It returns an
- * event code indicating which button has gone down. Note that we ignore
- * button-up transitions. Should be called repeatedly until it return
- * kInputEvent_None.
- * ========================================================================== */
- TInputEvent Input_GetEvent(
- void)
- {
- OSErr err;
- TInputEvent result = kInputEvent_None;
- ISpElementEvent event;
- Boolean gotEvent;
-
- if (gInputActive)
- {
- err = ISpElementList_GetNextEvent(gInputHoldDownEventList, sizeof(event), &event, &gotEvent);
- if (err == noErr && gotEvent)
- {
- result = (TInputEvent) event.refCon;
- if (event.data == kISpButtonUp)
- result += 1; // Note: we rely on off being on+1 (ie kInputEvent_InertialDampers_Off == kInputEvent_InertialDampers_On + 1)
- }
- else
- {
- err = ISpElementList_GetNextEvent(gInputEventList, sizeof(event), &event, &gotEvent);
-
- if (err == noErr && gotEvent && event.data == kISpButtonDown)
- result = (TInputEvent) event.refCon;
- }
- }
-
- return result;
- }
-
-
- /* =============================================================================
- * Input_Activate (external)
- *
- * On deactivation, we suspend InputSprocket. On activation we resume it and
- * flush the event queue. We only allow activation when the game is in "Play"
- * state.
- * ========================================================================== */
- void Input_Activate(
- Boolean inActivate)
- {
- Boolean doActivate;
-
- doActivate = inActivate;
- if (doActivate && Game_GetState() != kGameState_Playing)
- {
- doActivate = false;
- }
-
- if (gInputActive != doActivate)
- {
- gInputActive = doActivate;
-
- if (gInputActive)
- {
- #if USE_MOUSE_AND_KEYBOARD
- HideCursor();
- #endif
-
- ISpResume();
- ISpElementList_Flush(gInputEventList);
- }
- else
- {
- ISpSuspend();
-
- #if USE_MOUSE_AND_KEYBOARD
- ShowCursor();
- #endif
- }
- }
- }
-
-
-